import ply.lex as lex
import ply.yacc as yacc
from lexerinput import Lexerinput
from lexerinput import myLexError
import re
import os
from evaluator import Evaluator
from mimify import mp
from types import InstanceType
from wsgiref.validate import check_input


class Interpreter:
    """
    Base class for a lexer/parser that has the rules defined as methods
    """
    tokens = ()
    precedence = ()
    allinput = " "

    def __init__(self, **kw):
        self.debug = kw.get('debug', 0)
        self.variables = { }
        try:
            modname = os.path.split(os.path.splitext(__file__)[0])[1] + "_" + self.__class__.__name__
        except:
            modname = "parser" + "_" + self.__class__.__name__
        self.debugfile = modname + ".dbg"
        self.tabmodule = modname + "_" + "parsetab"
        #print self.debugfile, self.tabmodule
        # Build the lexer and parser
        self.xxer = lex.lex(module=self, debug=self.debug)
        yacc.yacc(module=self,
                  debug=self.debug,
                  debugfile=self.debugfile,
                  tabmodule=self.tabmodule)
        
    excmsg  = [" "]
    def run(self):
        #allinput = '''def fun( )\t begin\n print 3;\n  2 +=-\n end'''
        #del self.excmsg[:]
        #self.excmsg.extend(list(allinput))
        #Evaluator.visit(yacc.parse(allinput, lexer=self.xxer))
        mlexer = lex.lex(module=Lexerinput())
        while 1:
            allinput = ""
            try: 
                begincount = 0
                cp = "> "
                while 1:
                    #self.mlexer.token()
                    while 1: 
                        #petla po kazdej wczytanej linii z jej sprawdzeniem
                        s = raw_input(cp)
                        res = self.mcheck_input(s, mlexer)
                        if res:
                            break
                              
                    allinput += s + "\n"
                    #print allinput
                    s = re.sub('\"\w*\"', '\" \"', s)
                    #print s
                    if s.split().count("begin") > 0: 
                        begincount = begincount + 1
                        cp = cp.replace(">", "-->")
                        
                    if s.split().count("end") > 0:  
                        begincount = begincount - 1
                        cp = cp.replace("-->", ">")
                        
                    if begincount == 0:
                        allinput = self.rreplace(allinput, '\n', ' ', 1)
                        self.getLexer().lineno = 0
                        break
            except EOFError:
                break
            if not s:
                continue
            try:
                #print repr(allinput)
                del self.excmsg[:]
                self.excmsg.extend(list(allinput))
                Evaluator.visit(yacc.parse(allinput, lexer=self.xxer))               
            except RuntimeError:                    
                print "Maximum recursion depth exceeded"
#            except:                    
#                print "Undefined Error"
    def getLexer(self):
        return self.xxer  
               
    def rreplace(self, s, old, new, occurrence):
        li = s.rsplit(old, occurrence)
        return new.join(li) 
    
    def mcheck_input(self, s, mlexer):                    
        #sprawdzenie poprawnosci wprowadzonej linii
        mlexer.input(s)
        while 1:
            try:
                tok = mlexer.token()
                if not tok:
                    break
            except myLexError:
                print "Invalid input line. Try inserting it again"
                return False
        return True
    
    def find_column(self, input,token):
        charsinfile = token.lexpos 
        list = input.splitlines()
        #print list
        while 1:
            strline = list.pop(0)
            #print strline
            linelen = len(strline)
#            print charsinfile, linelen
            if charsinfile - linelen <= 0:
                return charsinfile
            else:
                charsinfile = charsinfile - linelen - 1

if __name__ == '__main__':
    eval = Evaluator()
    f = getattr(eval, "elo1")
    f()
